home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / chtiff / source / chtiff3.c < prev    next >
Text File  |  1993-07-08  |  15KB  |  669 lines

  1. /* TIFFの変換をサポートする関数群
  2.    8ビットからxビットへ膨らます関数。*/
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include"define.h"
  6. #define EXCHANGE_SECTION 1
  7. #include"function.h"
  8.  
  9. /* 8ビットタイル表示用 */
  10. unsigned char diffuse( unsigned int x, unsigned int y,
  11.                        unsigned short r, unsigned short g, unsigned short b )
  12. {
  13.     unsigned char ret;
  14.  
  15.     /* 上位3ビットが全て1ではなく、タイル化する点の時 */
  16.     if( ( r>>5 != 7 )&&( (x+y)&1 )&&( r&0x10 ) )
  17.              ret = (r&0xe0)+0x20;
  18.         else ret = (r&0xe0);
  19.  
  20.     if( ( g>>5 != 7 )&&( (x+y)&1 )&&( g&0x10 ) )
  21.              ret |= ((g&0xe0)+0x20)>>3;
  22.         else ret |= ((g&0xe0)     )>>3;
  23.  
  24.     /* 青は2ビットしかないので、4ドットを使ったタイル表示となる */
  25.     switch( (b>>4)&3 ){
  26.         case 0:
  27.             ret |= b>>6;
  28.             break;
  29.         case 1:
  30.             if( (b>>6 != 3)&&(y%2)&&(x%2) )
  31.                      ret |= (b>>6)+1;
  32.                 else ret |= (b>>6);
  33.             break;
  34.         case 2:
  35.             if( (b>>6 !=3)&&( (x+y)%2 ) )
  36.                      ret|= (b>>6)+1;
  37.                 else ret|= (b>>6);
  38.             break;
  39.         case 3:
  40.             if( (b>>6 != 3)&&( y%2 || x%2 ) )
  41.                      ret |= (b>>6)+1;
  42.                 else ret |= (b>>6);
  43.         }
  44.     return( ret );
  45. }
  46.  
  47.  
  48. /* タイル表示時のパレット作成 */
  49. void make_palet( void )
  50. {
  51.     unsigned int i,j;
  52.  
  53.     to.RED   = MALLOC( 512 );
  54.     to.GREEN = MALLOC( 512 );
  55.     to.BLUE  = MALLOC( 512 );
  56.  
  57.     for( i=0; i<256; i++ ){
  58.         j = i&0xe0;
  59.         *(to.RED  +i) = j<<8 | j<<5 | j<<2 | j>>1 | j>>4;
  60.         j = i&0x1c;
  61.         *(to.GREEN+i) = j<<11 | j<<8 | j<<5 | j<<2 | j>>1;
  62.         j = i & 0x03;
  63.         *(to.BLUE +i) = j<<14 | j<<12 | j<<10 | j<<8 | j<<6 | j<<4 | j<<2 | j;
  64.         }
  65. }
  66.  
  67.  
  68. /*
  69. このプログラムでは唯一パレットを使うモードです。
  70. 関数read_IFDでパレットを読み込み、short from.RED[],from.GREEN[],from.BLUE[]
  71. に各16ビットで色情報が記載されてます。
  72. よって、様々な変換はこのパレット情報を加工して行います。
  73. */
  74. void change8(int EXPAND)
  75. {
  76.     unsigned short w,r,x,R,G,B;
  77.  
  78.     puts("8Bit 画像データ変換を開始します。");
  79.  
  80.     x = 0;
  81.     *to.Strip_Offset=ftell(to.fp);
  82.  
  83.     switch(to.Bits_Per_Sample){
  84.     case 24:
  85.         while(1){
  86.             if( 256==(r=read_Gdata()) ) break;
  87.             R = *(from.RED   + r)>>8;
  88.             G = *(from.GREEN + r)>>8;
  89.             B = *(from.BLUE  + r)>>8;
  90.             write_Gdata( R );    /* REDと言えばRED5*/
  91.             write_Gdata( G );    /* GREEN */
  92.             write_Gdata( B );    /* BLUE */
  93.  
  94.             if( EXPAND ){
  95.                 if( (++x) % 3 == 0 ){
  96.                     write_Gdata( R );
  97.                     write_Gdata( G );
  98.                     write_Gdata( B );
  99.                     }
  100.                 if( x >= from.Image_Width ) x = 0;
  101.                 }
  102.             };
  103.         write_Gdata(256);
  104.         break;
  105.  
  106.     case 16:
  107.         while(1){
  108.             if( 256==(r=read_Gdata()) ) break;
  109.             w = ( (*(from.GREEN+r) & 0xf800) >> 1 )
  110.                |( (*(from.RED  +r) & 0xf800) >> 6 )
  111.                |( (*(from.BLUE +r) & 0xf800) >> 11);
  112.             write_Gdata( w & 0xff );
  113.             write_Gdata( w>>8 );
  114.  
  115.             if( EXPAND ){
  116.                 if( (++x) % 3 == 0 ){
  117.                     write_Gdata( w & 0xff );
  118.                     write_Gdata( w>>8 );
  119.                     }
  120.                 if( x >= from.Image_Width ) x = 0;
  121.                 }
  122.             }
  123.         write_Gdata(256);
  124.         break;
  125.  
  126.     case 8:
  127.         while( 256 != ( r=read_Gdata() ) ){
  128.             write_Gdata( r );
  129.             if( EXPAND ){
  130.                 if( (++x) % 3 == 0 ) write_Gdata( r );
  131.                 if( x >= from.Image_Width ) x = 0;
  132.                 }
  133.             }
  134.         write_Gdata(256);
  135.         to.RED   = from.RED;
  136.         to.GREEN = from.GREEN;
  137.         to.BLUE  = from.BLUE;
  138.         break;
  139.  
  140.     default:
  141.         puts("この変換には対応してません。");
  142.         return;
  143.         }
  144.  
  145.     puts("画像データ変換を終了しました。");
  146.     return;
  147. }
  148.  
  149.  
  150. /*
  151. Towns独自仕様16ビットです。16ビットの内訳をかきます。
  152. 一番左のビットはスーパーインポーズビットと呼ばれ、よく分かりません。
  153. (現在の対応では、16→16以外の変換では、無条件に0にしてます。)
  154. 残り15ビットは、5ビットずつ左からGRBの順に色データがあります。
  155. 各ピクセルは16ビットで一個ですから、short型で書き込むわけです。
  156. Townsはi80386CPUですから、上下バイトが入れ代わります。
  157.  
  158. さらに、NeXTのOpacity の関係で16bit になってるやつもついでに変換します。
  159. */
  160. void change16(int EXPAND)
  161. {
  162.     unsigned short w, r, r2, x, xx, y, b1, b2, R, G, B;
  163.  
  164.     puts("16Bit 画像データ変換を開始します。");
  165.  
  166.     x = 0;
  167.     *to.Strip_Offset=ftell(to.fp);
  168.  
  169.     if( from.Opacity ) goto RGBO;
  170.     switch(to.Bits_Per_Sample){
  171.     case 24:
  172.         while(1){
  173.             if( 256==(r2=read_Gdata()) ) break;
  174.             r = read_Gdata();
  175.             write_Gdata( (((r&0x3)<<6)|((r2&0xe0)>>2)) );    /* Red 5bits */
  176.             write_Gdata( (r&0x7c)<<1 );                        /* Green */
  177.             write_Gdata( (r2&0x1f)<<3 );                    /* Blue */
  178.  
  179.             if( EXPAND ){
  180.                 if( (++x) % 3 == 0 ){
  181.                     write_Gdata( (((r&0x3)<<6)|((r2&0xe0)>>2)) );
  182.                     write_Gdata( (r&0x7c)<<1 );
  183.                     write_Gdata( (r2&0x1f)<<3 );
  184.                     }
  185.                 if( x >= from.Image_Width ) x = 0;
  186.                 }
  187.             };
  188.         write_Gdata(256);
  189.         break;
  190.  
  191.     case 16:
  192.         r = 1;
  193.         while(1){
  194.             if( 256 == (r = read_Gdata()) ) break;
  195.             r2 = read_Gdata();
  196.             write_Gdata( r  );
  197.             write_Gdata( r2 );
  198.             if( EXPAND ){
  199.                 if( (++x) % 3 == 0 ){
  200.                     write_Gdata( r  );
  201.                     write_Gdata( r2 );
  202.                     }
  203.                 if( x >= from.Image_Width ) x = 0;
  204.                 }
  205.             }
  206.         write_Gdata(256);
  207.         break;
  208.  
  209.     case 8:
  210.         y = 0;
  211.         while(1){
  212.           x = 0;
  213.             for( xx=0; xx<from.Image_Width; xx++){
  214.                 if( 256==(r2=read_Gdata()) ) break;
  215.                 r = read_Gdata();
  216.                 R = ((r&0x3)<<6)|((r2&0xe0)>>2);    /* Red 5bits */
  217.                 G = (r&0x7c)<<1;                    /* Green */
  218.                 B = (r2&0x1f)<<3;                    /* Blue */
  219.  
  220.                 write_Gdata( diffuse( x, y, R, G, B ) );
  221.                 x++;
  222.                 if( (EXPAND)&&(xx%3 == 2) ){
  223.                   write_Gdata( diffuse( x, y, R, G, B ) );
  224.                   x++;
  225.                 }
  226.                 }
  227.             if( r2 == 256 ) break;
  228.             y++;
  229.             }
  230.         write_Gdata(256);
  231.         make_palet();
  232.         break;
  233.  
  234.  
  235.     default:
  236.         puts("この変換には対応してません。");
  237.         return;
  238.         }
  239.  
  240.     puts("画像データ変換を終了しました。");
  241.     return;
  242.     
  243.     RGBO:    /* ううぅぅ・・・こんなフォーマットがあろうとは・・・ */
  244.     switch(to.Bits_Per_Sample){
  245.     case 24:
  246.         while( 256 != (b1=read_Gdata()) ){
  247.             b2 = read_Gdata();
  248.  
  249.             R = b1 & 0xf0; R |= (R>>4);
  250.             G = b1 & 0xf;  G |= (G<<4);
  251.             B = b2 & 0xf0; B |= (B>>4);
  252.             write_Gdata( R );    /* RED5(しつこい!) */
  253.             write_Gdata( G );    /* GREEN */
  254.             write_Gdata( B );    /* BLUE */
  255.  
  256.             if( EXPAND ){
  257.                 if( (++x) % 3 == 0 ){
  258.                     write_Gdata( R );
  259.                     write_Gdata( G );
  260.                     write_Gdata( B );
  261.                     }
  262.                 if( x >= from.Image_Width ) x = 0;
  263.                 }
  264.             }
  265.         write_Gdata(256);    /* 出力終了 */
  266.         break;
  267.  
  268.  
  269.     case 16:
  270.         w = from.Image_Width;
  271.         while( 256 != (b1=read_Gdata()) ){
  272.             b2 = read_Gdata();
  273.  
  274.             R = b1 & 0xf0; R |= (G>>4);
  275.             G = b1 & 0xf;  G |= (G<<4);
  276.             B = b2 & 0xf0; B |= (B>>4);
  277.             b1 = ( (R & 0xf8)<<2 ) | ( (G & 0xf8)<<7 ) | ( (B & 0xf8)>>3 );
  278.             write_Gdata( b1 & 0xff );
  279.             write_Gdata( b1 >> 8 );
  280.  
  281.             if( EXPAND ){
  282.                 if( (++x) % 3 == 0 ){
  283.                     write_Gdata( b1 & 0xff );
  284.                     write_Gdata( b1 >> 8 );
  285.                     }
  286.                 if( x >= from.Image_Width ) x = 0;
  287.                 }
  288.             }
  289.         write_Gdata(256);    /* 出力終了 */
  290.         break;
  291.  
  292.     case 8:
  293.         y = 0;
  294.         while(1){
  295.             for( x=0; x<from.Image_Width; x++){
  296.                 if( 256==(b1=read_Gdata()) ) break;
  297.                 b2 = read_Gdata();
  298.  
  299.                 R = b1 & 0xf0;
  300.                 G = (b1 & 0xf)<<4;
  301.                 B = b2 & 0xf0;
  302.  
  303.                 w = diffuse( x, y, R, G, B );
  304.                 write_Gdata( w );
  305.                 if( (EXPAND)&&(xx%3 == 2) ) write_Gdata( w );
  306.                 }
  307.             if( b1 == 256 ) break;
  308.             y++;
  309.             }
  310.         write_Gdata(256);
  311.         make_palet();
  312.         break;
  313.  
  314.  
  315.     default:
  316.         puts("この変換には対応してません。");
  317.         return;
  318.     }
  319.  
  320.     puts("画像データ変換を終了しました。");
  321.     return;
  322. }
  323.  
  324.  
  325. /*
  326. TIFF 5.0 でフルカラーとされている24ビットモードです。
  327. 連続する3バイトが1ピクセルで、RGBの順で各8ビットが割り振られており、
  328. モトローラ・インテルの差もなく、一番扱いやすいデータです。
  329. */
  330. void change24(int EXPAND)
  331. {
  332.     unsigned short w, r, g, b, x, xx, y;
  333.  
  334.     puts("24Bit 画像データ変換を開始します。");
  335.  
  336.     x = 0;    /* 今横座標のどこを書き込んでるのか */
  337.     *to.Strip_Offset=ftell(to.fp);
  338.  
  339.     switch(to.Bits_Per_Sample){
  340.     case 24:
  341.         r = 1;
  342.         while(1){
  343.             write_Gdata( r = read_Gdata() );
  344.             if( r == 256 ) break;
  345.             write_Gdata( g = read_Gdata() );
  346.             write_Gdata( b = read_Gdata() );
  347.  
  348.             if( EXPAND ){
  349.                 if( (++x) % 3 == 0 ){
  350.                     write_Gdata( r );
  351.                     write_Gdata( g );
  352.                     write_Gdata( b );
  353.                     }
  354.                 if( x >= from.Image_Width ) x = 0;
  355.                 }
  356.             }
  357.         break;
  358.  
  359.     case 16:
  360.         while(1){
  361.             if( 256==(r=read_Gdata()) ) break;
  362.             g = read_Gdata() & 0xf8;
  363.             b = read_Gdata() & 0xf8;
  364.             w = ( (r & 0x00f8) << 2 ) | ( g << 7 ) | ( b >> 3 );
  365.             write_Gdata( w & 0xff );
  366.             write_Gdata( w>>8 );
  367.             if( EXPAND ){
  368.                 if( (++x) % 3 == 0 ){
  369.                     write_Gdata( w & 0xff );
  370.                     write_Gdata( w>>8 );
  371.                     }
  372.                 if( x >= from.Image_Width ) x = 0;
  373.                 }
  374.             }
  375.         write_Gdata(256);
  376.         break;
  377.  
  378.  
  379.     case 8:
  380.         y = 0;
  381.         while(1){
  382.           x = 0;
  383.           for( xx=0; xx<from.Image_Width; xx++){
  384.                 if( 256==(r=read_Gdata()) ) break;
  385.                 g = read_Gdata();
  386.                 b = read_Gdata();
  387.  
  388.                 write_Gdata( diffuse( x, y, r, g, b ) );
  389.                 x++;
  390.                 if( (EXPAND)&&(xx%3 == 2) ){
  391.                   write_Gdata( diffuse( x, y, r, g, b ) );
  392.                   x++;
  393.                 }
  394.                 }
  395.             if( r==256 ) break;
  396.             y++;
  397.             }
  398.         write_Gdata(256);
  399.         make_palet();
  400.         break;
  401.  
  402.  
  403.     default:
  404.         puts("この変換には対応してません。");
  405.         return;
  406.     }
  407.  
  408.     puts("画像データ変換を終了しました。");
  409.     return;
  410. }
  411.  
  412.  
  413.  
  414. /*
  415. NeXTの標準、12ビットフォーマットです。これも独自使用だとは思います。
  416. 画像の幅が、奇数か偶数かで処理が違うので、その分遅くなるかも・・・
  417. */
  418. void change12(int EXPAND)
  419. {
  420.     unsigned short w,b1,b2,r,g,b,x,xx,y;
  421.     /*
  422.     r,g,b:いわずと知れたRGB成分
  423.     w    :今、出力画像ラインのどこを処理してるかのカウンタ
  424.     x    :今、入力画像ラインのどこを処理してるかのカウンタ
  425.     b1,b2: byte1 byte2
  426.     */
  427.  
  428.     puts("12Bit 画像データ変換を開始します。");
  429.  
  430.     x = 0;
  431.     *to.Strip_Offset = ftell(to.fp);
  432.  
  433.     switch(to.Bits_Per_Sample){
  434.     case 24:
  435.         w = from.Image_Width;
  436.         while( 256 != (b1=read_Gdata()) ){
  437.             b2 = read_Gdata();
  438.  
  439.             /* 奇数ピクセルの書き込み */
  440.             r = b1 & 0xf0; r |= (r>>4);
  441.             g = b1 & 0xf;  g |= (g<<4);
  442.             b = b2 & 0xf0; b |= (b>>4);
  443.             write_Gdata( r );    /* RED5(しつこい!) */
  444.             write_Gdata( g );    /* GREEN */
  445.             write_Gdata( b );    /* BLUE */
  446.  
  447.             if( EXPAND ){
  448.                 if( (++x) % 3 == 0 ){
  449.                     write_Gdata( r );
  450.                     write_Gdata( g );
  451.                     write_Gdata( b );
  452.                     }
  453.                 if( x >= from.Image_Width ) x = 0;
  454.                 }
  455.  
  456.             /* 偶数ピクセルの書き込み */
  457.             if( w != 1 ){    /* 各ラインの最終ピクセルかどうか */
  458.                 b1 = read_Gdata();
  459.                 r = b2 & 0xf;  r |= (r<<4);
  460.                 g = b1 & 0xf0; g |= (g>>4);
  461.                 b = b1 & 0xf;  b |= (b<<4);
  462.                 write_Gdata( r );    /* RED5(しつこい!) */
  463.                 write_Gdata( g );    /* GREEN */
  464.                 write_Gdata( b );    /* BLUE */
  465.                 w -= 2;
  466.                 if( w == 0 ) w = to.Image_Width;
  467.  
  468.                 if( EXPAND ){
  469.                     if( (++x) % 3 == 0 ){
  470.                         write_Gdata( r );
  471.                         write_Gdata( g );
  472.                         write_Gdata( b );
  473.                         }
  474.                     if( x >= from.Image_Width ) x = 0;
  475.                     }
  476.                 }
  477.             else w = from.Image_Width;
  478.             }
  479.         write_Gdata(256);    /* 出力終了 */
  480.         break;
  481.  
  482.  
  483.     case 16:
  484.         w = from.Image_Width;
  485.         while( 256 != (b1=read_Gdata()) ){
  486.             b2 = read_Gdata();
  487.  
  488.             /* 奇数ピクセルの書き込み */
  489.             r = b1 & 0xf0; r |= (r>>4);
  490.             g = b1 & 0xf;  g |= (g<<4);
  491.             b = b2 & 0xf0; b |= (b>>4);
  492.             b1 = ( (r & 0xf8)<<2 ) | ( (g & 0xf8)<<7 ) | ( (b & 0xf8)>>3 );
  493.             write_Gdata( b1 & 0xff );
  494.             write_Gdata( b1 >> 8 );
  495.  
  496.             if( EXPAND ){
  497.                 if( (++x) % 3 == 0 ){
  498.                     write_Gdata( b1 & 0xff );
  499.                     write_Gdata( b1 >> 8 );
  500.                     }
  501.                 if( x >= from.Image_Width ) x = 0;
  502.                 }
  503.  
  504.             /* 偶数ピクセルの書き込み */
  505.             if( w != 1 ){    /* 各ラインの最終ピクセルかどうか */
  506.                 b1 = read_Gdata();
  507.                 r = b2 & 0xf;  r |= (r<<4);
  508.                 g = b1 & 0xf0; g |= (g>>4);
  509.                 b = b1 & 0xf;  b |= (b<<4);
  510.  
  511.                 b1 = ( (r & 0xf8)<<2 ) | ( (g & 0xf8)<<7 ) | ( (b & 0xf8)>>3 );
  512.                 write_Gdata( b1 & 0xff );
  513.                 write_Gdata( b1 >> 8 );
  514.  
  515.                 w -= 2;
  516.                 if( w == 0 ) w = to.Image_Width;
  517.  
  518.                 if( EXPAND ){
  519.                     if( (++x) % 3 == 0 ){
  520.                         write_Gdata( b1 & 0xff );
  521.                         write_Gdata( b1 >> 8 );
  522.                         }
  523.                     if( x >= from.Image_Width ) x = 0;
  524.                     }
  525.                 }
  526.             else w = from.Image_Width;
  527.             }
  528.         write_Gdata(256);    /* 出力終了 */
  529.         break;
  530.  
  531.     case 8:
  532.         y = 0;
  533.         while(1){
  534.           x = 0;
  535.             for( xx=0; xx<from.Image_Width; xx+=2 ){
  536.                 if( 256 == (b1=read_Gdata()) ) break;
  537.                 b2 = read_Gdata();
  538.  
  539.                 /* 奇数ピクセルの書き込み */
  540.                 r = b1 & 0xf0;
  541.                 g = (b1 & 0xf)<<4;
  542.                 b = b2 & 0xf0;
  543.                 write_Gdata( diffuse( x, y, r, g, b ) );
  544.                 x++;
  545.                 if( EXPAND&&(xx%3 == 2) ){
  546.                   write_Gdata( diffuse( x, y, r, g, b ) );
  547.                   x++;
  548.                 }
  549.  
  550.                 /* 偶数ピクセルの書き込み */
  551.                 if( from.Image_Width-xx != 1 ){    /* ラインの最終ピクセルか */
  552.                     b1 = read_Gdata();
  553.                     r = (b2 & 0xf)<<4;
  554.                     g = b1 & 0xf0;
  555.                     b = (b1 & 0xf)<<4;
  556.                     write_Gdata( diffuse( x, y, r, g, b ) );
  557.                     x++;
  558.                     if( EXPAND&&(xx%3 == 0) ){
  559.                       write_Gdata( diffuse( x, y, r, g, b ) );
  560.                       x++;
  561.                     }
  562.                     }
  563.                 }
  564.             if( b1 == 256 ) break;
  565.             y++;
  566.             }
  567.  
  568.         write_Gdata(256);
  569.         make_palet();
  570.         break;
  571.  
  572.  
  573.     default:
  574.         puts("この変換には対応してません。");
  575.         return;
  576.         }
  577.  
  578.     puts("画像データ変換を終了しました。");
  579.     return;
  580. }
  581.  
  582.  
  583. /*
  584. TIFF 5.0 でフルカラーとされている24ビットモードに、不透明度を加えたやつです。
  585. */
  586. void change32(int EXPAND)
  587. {
  588.     unsigned short w,r,g,b,x,xx,y;
  589.  
  590.     puts("32Bit 画像データ変換を開始します。");
  591.  
  592.     x = 0;    /* 今横座標のどこを書き込んでるのか */
  593.     *to.Strip_Offset=ftell(to.fp);
  594.  
  595.     switch(to.Bits_Per_Sample){
  596.     case 24:
  597.         r = 1;
  598.         while(1){
  599.             write_Gdata( r = read_Gdata() );
  600.             if( r == 256 ) break;
  601.             write_Gdata( g = read_Gdata() );
  602.             write_Gdata( b = read_Gdata() );
  603.             read_Gdata();    /* Opacity 空読み */
  604.  
  605.             if( EXPAND ){
  606.                 if( (++x) % 3 == 0 ){
  607.                     write_Gdata( r );
  608.                     write_Gdata( g );
  609.                     write_Gdata( b );
  610.                     }
  611.                 if( x >= from.Image_Width ) x = 0;
  612.                 }
  613.             }
  614.         break;
  615.  
  616.     case 16:
  617.         while(1){
  618.             if( 256==(r=read_Gdata()) ) break;
  619.             g = read_Gdata() & 0xf8;
  620.             b = read_Gdata() & 0xf8;
  621.             read_Gdata();    /* Opacity 空読み */
  622.             w = ( (r & 0x00f8) << 2 ) | ( g << 7 ) | ( b >> 3 );
  623.             write_Gdata( w & 0xff );
  624.             write_Gdata( w>>8 );
  625.             if( EXPAND ){
  626.                 if( (++x) % 3 == 0 ){
  627.                     write_Gdata( w & 0xff );
  628.                     write_Gdata( w>>8 );
  629.                     }
  630.                 if( x >= from.Image_Width ) x = 0;
  631.                 }
  632.             }
  633.         write_Gdata(256);
  634.         break;
  635.  
  636.     case 8:
  637.         y = 0;
  638.         while(1){
  639.           x = 0;
  640.             for( xx=0; xx<from.Image_Width; xx++){
  641.                 if( 256==(r=read_Gdata()) ) break;
  642.                 g = read_Gdata();
  643.                 b = read_Gdata();
  644.                 read_Gdata();    /* Opacity 空読み */
  645.  
  646.                 write_Gdata( diffuse( x, y, r, g, b ) );
  647.                 x++;
  648.                 if( (EXPAND)&&(xx%3 == 2) ){
  649.                   write_Gdata( diffuse( x, y, r, g, b ) );
  650.                   x++;
  651.                 }
  652.                 }
  653.             if( r==256 ) break;
  654.             y++;
  655.             }
  656.         write_Gdata(256);
  657.         make_palet();
  658.         break;
  659.  
  660.  
  661.     default:
  662.         puts("この変換には対応してません。");
  663.         return;
  664.         }
  665.  
  666.     puts("画像データ変換を終了しました。");
  667.     return;
  668. }
  669.